<?php
/**
 *  💡 免责声明：本软件不得用于商业用途，仅做学习交流
 *  ⚠️ 权利声明：本软件由版权人提供产品技术支持
 *  📅 项目编号：NX2025-0135
 */
namespace App\Jobs;

use App\Models\User;
use App\Models\UserTotalRevenue;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;

/**
 * 每次成功付款更新用户及父级收益.
 */
class UpdateUserRevenueJob implements ShouldQueue
{
    use Dispatchable;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;

    public $tries = 5;

    public $maxExceptions = 3;

    public $backoff = [30, 60, 300, 600, 1800];

    public $timeout = 300;

    private $user;

    private $amount;

    private $type;

    public function __construct(User $user, $amount, $type)
    {
        $this->user = $user;
        $this->amount = $amount;
        $this->type = $type;
    }

    public function handle()
    {
        $ids = $this->getAncestorsIds();
        $this->addValue($ids);
    }

    private function addValue($userIds)
    {
        DB::transaction(function () use ($userIds) {
            $records = UserTotalRevenue::with('user')
                ->whereIn('user_id', $userIds)
                ->orderBy('user_id')
                ->lockForUpdate()
                ->get();

            foreach ($records as $record) {
                $isSelf = ($record->user_id == $this->user->id);
                $updateFields = ['updated_at' => now()];

                if ($isSelf) {
                    $updateFields['self'] = DB::raw("`self` + {$this->amount}");
                    $this->type == 1
                        ? $updateFields['product'] = DB::raw("`product` + {$this->amount}")
                        : $updateFields['group'] = DB::raw("`group` + {$this->amount}");
                } else {
                    $updateFields['value'] = DB::raw("`value` + {$this->amount}");
                    $this->type == 1
                        ? $updateFields['product_team'] = DB::raw("`product_team` + {$this->amount}")
                        : $updateFields['group_team'] = DB::raw("`group_team` + {$this->amount}");
                }
                UserTotalRevenue::where('id', $record->id)->update($updateFields);
                if ($record->user->team > 0) {
                    UserAgentLevelJob::dispatch($record->user)
                        ->onQueue('user_agent_level');
                }
            }
        });
    }

    /**
     * @return mixed
     */
    private function getAncestorsIds()
    {
        return $this->user->queryAncestorsAndSelf()->select('id')->pluck('id')->toArray();
    }
}
